package 面试代码;

/**
 * 代码挺长的,写起来还是有点难度的,逻辑不难
 *
 * 华测导航面试官让队列的方式实现生产者消费者模型,下来深度了解了一下
 * 生产者消费者模型这块深度学习还是挺有深度的
 */
public class 生产者消费者模型 {
    public static void main(String[] args) {
        During during = new During();
        Producer p = new Producer(during);
        p.setName("生产者");
        Consumer c1 = new Consumer(during);
        c1.setName("消费者1");
        Consumer c2 = new Consumer(during);
        c2.setName("消费者2");
        p.start();
        c1.start();
        c2.start();
    }
}
class During{
    private int productCount = 0;
    //生产产品
    public synchronized void produceProduct() {
        if(productCount < 20){
            productCount++;
            System.out.println(Thread.currentThread().getName() + ":开始生产第" + productCount + "个产品");
            notify();
        }else{
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //消费产品
    public synchronized void consumeProduct() {
        if(productCount > 0){
            System.out.println(Thread.currentThread().getName() + ":开始消费第" + productCount + "个产品");
            productCount--;
            notify();
        }else{
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Producer extends Thread{//生产者
    private During during;
    public Producer(During during){
        this.during = during;
    }
    @Override
    public void run() {
        System.out.println(getName() + ":开始生产产品.....");
        while(true){
            try {
                sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            during.produceProduct();
        }
    }
}
class Consumer extends Thread{//消费者
    private During during;
    public Consumer(During clerk){
        this.during = clerk;
    }
    @Override
    public void run() {
        System.out.println(getName() + ":开始消费产品.....");
        while(true){
            try {
                sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            during.consumeProduct();
        }
    }
}
